import 'package:flutter_graphics_view/src/context/scene_model_context.dart';
import 'package:flutter_graphics_view/src/context/scene_state_context.dart';
import 'package:flutter_graphics_view/src/io/scene_model_reader.dart';
import 'package:flutter_graphics_view/src/io/scene_model_writer.dart';
import 'package:flutter_graphics_view/src/io/scene_reader.dart';
import 'package:flutter_graphics_view/src/io/scene_state_reader.dart';
import 'package:flutter_graphics_view/src/io/scene_state_writer.dart';
import 'package:flutter_graphics_view/src/io/scene_writer.dart';
import 'package:flutter_graphics_view/src/policy/base/policy_set.dart';

class GraphicsViewContext {
  final SceneModelContext _sceneModelContext;
  final SceneStateContext _sceneStateContext;
  final PolicySet policySet;

  SceneModelContext get sceneModelContext => _sceneModelContext;

  SceneStateContext get sceneStateContext => _sceneStateContext;

  GraphicsViewContext({required this.policySet})
      : this._sceneModelContext = SceneModelContext(policySet),
        this._sceneStateContext = SceneStateContext() {
    policySet.initializePolicy(_getSceneReader(), _getSceneWriter());
  }

  GraphicsViewContext.withSharedModel(
    GraphicsViewContext oldContext, {
    required this.policySet,
  })  : this._sceneModelContext = oldContext.sceneModelContext,
        this._sceneStateContext = SceneStateContext() {
    policySet.initializePolicy(_getSceneReader(), _getSceneWriter());
  }

  GraphicsViewContext.withSharedState(
    GraphicsViewContext oldContext, {
    required this.policySet,
  })  : this._sceneModelContext = SceneModelContext(policySet),
        this._sceneStateContext = oldContext.sceneStateContext {
    policySet.initializePolicy(_getSceneReader(), _getSceneWriter());
  }

  GraphicsViewContext.withSharedModelAndState(
    GraphicsViewContext oldContext, {
    required this.policySet,
  })  : this._sceneModelContext = oldContext.sceneModelContext,
        this._sceneStateContext = oldContext.sceneStateContext {
    policySet.initializePolicy(_getSceneReader(), _getSceneWriter());
  }

  SceneReader _getSceneReader() {
    return SceneReader(SceneModelReader(sceneModelContext, sceneStateContext),
        SceneStateReader(sceneStateContext));
  }

  SceneWriter _getSceneWriter() {
    return SceneWriter(SceneModelWriter(sceneModelContext, sceneStateContext),
        SceneStateWriter(sceneStateContext));
  }
}
